import 'dart:math';

import 'package:flutter/material.dart';
import 'package:x3_charts_core/chart_tools/chart_tools.dart';
import 'package:x3_charts_core/model/layered_cake_pie_chart_model.dart';

///**
///* @author hrongyong
///* @date   3/4/21
///* @email hrongyong@gmail.com
///* Description:
///*/

class LayeredCakePieCharPainter extends CustomPainter {
  final List<LayeredCakePieChartModel> chartList;

  ///动画数值
  final Animation<double> repaint;

  ///背景颜色
  final Color backgroundColor;

  ///默认饼块颜色
  final Color defaultColor;

  ///边距大小 - 用于调整四周的边距预留位置 width:横向边距 height：纵向边距
  final Size marginSize;

  LayeredCakePieCharPainter({
    @required this.chartList,
    this.repaint,
    this.backgroundColor = Colors.white,
    this.defaultColor = Colors.lightBlueAccent,
    this.marginSize,
  }) : super(repaint: repaint);

  ///最大半径
  double maxRadius = 0.0;

  Paint _paint = Paint()..isAntiAlias = true;

  ///圆的度数
  final double CIRCLE_ANGLE = 360;

  ///刻度的长度
  final double scaleLength = 10;

  ///间距
  EdgeInsets chartPadding;

  ///最里层宽度
  double innermostWidth = 0.0;

  ///中间层宽度
  double middleLayerWidth = 0.0;

  ///最外层宽度
  double outermostWidth = 0.0;

  ///文字
  final TextPainter _textPainter = TextPainter(textDirection: TextDirection.ltr);

  @override
  void paint(Canvas canvas, Size size) {
    if (chartList == null || chartList.length == 0) return;

    ///调整边距
    chartPadding = EdgeInsets.only(left: marginSize.width + 15, top: marginSize.height + 10, right: marginSize.width + 15, bottom: marginSize.height + 10);

    ///确定最大半径
    maxRadius = min((size.width - chartPadding.left - chartPadding.right - scaleLength * 2) / 2, (size.height - chartPadding.bottom - chartPadding.top - scaleLength * 2) / 2);
    innermostWidth = maxRadius * 0.2;
    middleLayerWidth = maxRadius * 2 / 3 - innermostWidth;
    outermostWidth = maxRadius / 3;

    ///绘制背景
    canvas.drawRect(Offset.zero & size, Paint()..color = backgroundColor);

    ///移动绘画中心
    canvas.translate(size.width / 2, size.height / 2);

    ///绘制最里层（中心圆点）
    _drawInnermostLayer(canvas, size);

    ///绘制中间层 （中间层圆环）
    _drawMiddleLayer(canvas, size);

    ///绘制中间层的描述 （在中间层圆环的中心并且旋转圆环中心的角度）
    _drawMiddleLayerDescription(canvas, size);

    ///绘制最外层 (最外层圆环)
    _drawOutermostLayer(canvas, size);

    ///绘制最外层圆环上的延伸刻度线和文本
    drawOutermostLayerTickMarksAndText(canvas, size);
  }

  ///绘制最外层描述文字
  drawOutermostLayerText(Canvas canvas, Size size, {String title, Offset offset}) {
    TextSpan text = TextSpan(text: title, style: TextStyle(fontSize: 6, color: Colors.black, fontWeight: FontWeight.bold));
    _textPainter.text = text;
    _textPainter.layout(); // 进行布局
    Size textSize = _textPainter.size;
    Offset textOffsetPos = ChartTools.roundStructureTextOffset(offset: offset, textSize: textSize)[0];
    _textPainter.paint(canvas, textOffsetPos);
  }

  ///绘制圆环上的延伸刻度线和文本
  drawOutermostLayerTickMarksAndText(Canvas canvas, Size size) {
    canvas.save();

    ///累计的弧度
    double grandTotal = 0.0;
    chartList.forEach((element) {
      element.viceCake.forEach((viceCakeElement) {
        double x1 = (maxRadius + 2) * sin(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * viceCakeElement.cakeSize) / 2));
        double y1 = -(maxRadius + 2) * cos(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * viceCakeElement.cakeSize) / 2));
        double x2 = (maxRadius + scaleLength) * sin(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * viceCakeElement.cakeSize) / 2));
        double y2 = -(maxRadius + scaleLength) * cos(ChartTools.degToRad(grandTotal + (CIRCLE_ANGLE * viceCakeElement.cakeSize) / 2));

        ///绘制刻度线
        canvas.drawLine(
            Offset(x1, y1),
            Offset(x2, y2),
            Paint()
              ..color = viceCakeElement.cakeColor == null ? defaultColor : viceCakeElement.cakeColor
              ..strokeWidth = 2);

        ///绘制文字
        drawOutermostLayerText(
          canvas,
          size,
          title: viceCakeElement.cakeDescription,
          offset: Offset(x2, y2),
        );
        grandTotal += CIRCLE_ANGLE * viceCakeElement.cakeSize;
      });
    });

    canvas.restore();
  }

  ///绘制最外层 (最外层圆环)
  _drawOutermostLayer(Canvas canvas, Size size) {
    canvas.save();
    canvas.rotate(-pi / 2);

    ///最外层旋转角度
    double outermostStartAngle = 0.0;
    Rect rect = Rect.fromCenter(center: Offset.zero, width: innermostWidth * 2 + middleLayerWidth * 2 + outermostWidth, height: innermostWidth * 2 + middleLayerWidth * 2 + outermostWidth);
    chartList.forEach((element) {
      element.viceCake.forEach((viceCakeElement) {
        canvas.drawArc(
            rect,
            outermostStartAngle * repaint.value,
            (2 * pi) * viceCakeElement.cakeSize * repaint.value,
            false,
            _paint
              ..style = PaintingStyle.stroke
              ..strokeWidth = outermostWidth
              ..color = viceCakeElement.cakeColor == null ? defaultColor : viceCakeElement.cakeColor);
        outermostStartAngle += (2 * pi) * viceCakeElement.cakeSize;
      });
    });

    canvas.restore();
  }

  ///绘制中间层的描述 （在中间层圆环的中心并且旋转圆环中心的角度）
  _drawMiddleLayerDescription(Canvas canvas, Size size) {
    canvas.save();
    canvas.rotate(-pi / 2);

    ///描述的绘画中心距离半径的距离
    double descriptionRadius = innermostWidth + middleLayerWidth / 2;
    double startAngle = 0.0;
    chartList.forEach((element) {
      ///旋转角度
      canvas.rotate((startAngle + (2 * pi) * element.mainCake.cakeSize / 2));

      ///绘制中间层的描述文字
      _drawMiddleLayerDescriptionText(
        canvas,
        size,
        title: element.mainCake.cakeDescription,
        offset: Offset(descriptionRadius, 0),
      );
      canvas.rotate(-(startAngle + (2 * pi) * element.mainCake.cakeSize / 2));
      startAngle += (2 * pi) * element.mainCake.cakeSize;
    });
    canvas.restore();
  }

  ///绘制中间层的描述文字
  _drawMiddleLayerDescriptionText(Canvas canvas, Size size, {String title, Offset offset}) {
    TextSpan text = TextSpan(text: title, style: TextStyle(fontSize: 6, color: Colors.white, fontWeight: FontWeight.bold));
    _textPainter.text = text;
    _textPainter.layout(); // 进行布局
    Size textSize = _textPainter.size;
    Offset textOffsetPos = Offset(offset.dx, offset.dy - textSize.height / 2);
    _textPainter.paint(canvas, textOffsetPos);
  }

  ///绘制中间层 （中间层圆环）
  _drawMiddleLayer(Canvas canvas, Size size) {
    canvas.save();
    Rect rect = Rect.fromCenter(center: Offset.zero, width: innermostWidth * 2 + middleLayerWidth, height: innermostWidth * 2 + middleLayerWidth);
    canvas.rotate(-pi / 2);
    double startAngle = 0.0;
    chartList.forEach((element) {
      canvas.drawArc(
          rect,
          startAngle * repaint.value,
          (2 * pi) * element.mainCake.cakeSize * repaint.value,
          false,
          _paint
            ..style = PaintingStyle.stroke
            ..strokeWidth = middleLayerWidth
            ..color = element.mainCake.cakeColor == null ? defaultColor : element.mainCake.cakeColor);

      startAngle += (2 * pi) * element.mainCake.cakeSize;
    });
    canvas.restore();
  }

  ///绘制最里层（中心圆点）
  _drawInnermostLayer(Canvas canvas, Size size) {
    canvas.save();
    canvas.drawCircle(Offset.zero, innermostWidth, Paint()..color = backgroundColor);
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
